Go

您所在的位置:网站首页 golang error code Go

Go

#Go| 来源: 网络整理| 查看: 265

文章目录 1.服务端代码2.客户端代码3.发起请求报错4.问题分析5.解决方法

1.服务端代码 package main import ( "github.com/gin-gonic/gin" "github.com/micro/go-micro/registry" "github.com/micro/go-micro/web" "github.com/micro/go-plugins/registry/consul" "net/http" ) func main() { consulReg := consul.NewRegistry(registry.Addrs(":8500")) engine := gin.Default() engine.POST("/hello", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg": "hello,world", }) }) service := web.NewService( web.Name("cas"), web.Address(":8001"), web.Registry(consulReg), web.Handler(engine), ) service.Init() service.Run() } 2.客户端代码 package main import ( "context" "github.com/micro/go-micro/client" "github.com/micro/go-micro/client/selector" "github.com/micro/go-micro/registry" "github.com/micro/go-plugins/client/http" "github.com/micro/go-plugins/registry/consul" "log" ) func main() { consulReg := consul.NewRegistry(registry.Addrs(":8500")) selector := selector.NewSelector( selector.Registry(consulReg), selector.SetStrategy(selector.RoundRobin), ) httpClient := http.NewClient( // 选择器 client.Selector(selector), // 响应格式默认格式protobuf,设置为json client.ContentType("application/json"), ) req := map[string]string{} request := httpClient.NewRequest("cas", "/hello", req) rsp := map[string]interface{}{} err := httpClient.Call(context.Background(), request, &rsp) if err != nil { log.Fatalf("request err: %+v", err) } log.Printf("%+v",rsp) } 3.发起请求报错

客户端请求报错如下:

{"id":"go.micro.client","code":500,"detail":"none available","status":"Internal Server Error"} 4.问题分析

1.顺着客户端调用的Call()方法,进入源码github.com\micro\go-plugins\client\http\http.go,找到获取服务节点的方法:

// get next nodes from the selector next, err := h.next(req, callOpts)

2.再继续查看next()方法,找到第63行,这里为Selector节点选择器添加了过滤器,传递了两个参数"protocol", "http",可以发现是个键值对:

// only get the things that are of mucp protocol selectOptions := append(opts.SelectOptions, selector.WithFilter( selector.FilterLabel("protocol", "http"), ))

3.进一步进入FilterLabel()方法,在第41行可以发现,上一步传的两个参数在这里做了校验,分别作为的Metadata(元数据)的map的键和值,相当于验证协议需要为http:

if node.Metadata[key] == val { nodes = append(nodes, node) }

4.回到http.go的69行,如果不满足http协议,则获取服务节点失败,返回我们所遇到的这个err:

// get next nodes from the selector next, err := h.opts.Selector.Select(service, selectOptions...) if err != nil && err == selector.ErrNotFound { return nil, errors.NotFound("go.micro.client", err.Error()) } else if err != nil { return nil, errors.InternalServerError("go.micro.client", err.Error()) }

到这里其实已经可以基本确定我们遇到的问题了:在使用go-plugins插件进行服务调用时,在服务发现时为选择器添加了过滤,限定了请求协议,要求Metadata的键值必须为"protocol":"http",否则返回的服务节点切片长度将为0。

5.解决方法

因此解决方法则是在服务端进行服务注册的时候,为注册的服务添加上Metadata配置,指定请求协议为http:

service := web.NewService( web.Name("cas"), web.Address(":8001"), web.Registry(consulReg), web.Handler(engine), // 为注册的服务添加Metadata,指定请求协议为http web.Metadata(map[string]string{"protocol" : "http"}), )

在指定了服务的请求协议后,成功解决该问题~😄



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3